package com.wb3.meta.api.core.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.alibaba.fastjson.JSONObject;
import com.wb3.meta.api.core.dao.UsersMapper;
import com.wb3.meta.api.core.model.Users;
import com.wb3.meta.api.core.service.MyToysService;
import com.wb3.meta.api.core.service.UsersService;
import com.wb3.meta.api.core.vo.*;
import com.wb3.meta.common.enums.EnumConstants;
import com.wb3.meta.common.pojo.ResultT;
import com.wb3.meta.common.utils.JwtUtil;
import com.github.pagehelper.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service("usersService")
@AllArgsConstructor
@Lazy
@Transactional(transactionManager = "dataSourceTransactionManagerOne", rollbackFor = Exception.class)
public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersMapper usersMapper;
    private final WxMaService wxMaService;

    @Autowired
    private MyToysService myToysService;


    /**
     * 分页查询方法
     *
     * @param vo
     * @return
     */
    @Override
    public Page<ResUsersVo> getModelPage(ReqUsersVo vo) {
        return null;
    }

    /**
     * 列表查询方法 -返回 res 对象
     *
     * @param vo
     * @return
     */
    @Override
    public List<ResUsersVo> getModelListByConditions(ReqUsersVo vo) {
        return usersMapper.getModelListByConditions(vo);
    }

    /**
     * 根据条件查询单条数据方法，返回res vo类
     *
     * @param vo
     * @return
     */
    @Override
    public ResUsersVo getResModelByConditions(ReqUsersVo vo) {
        return usersMapper.getResModelByConditions(vo);
    }

    /**
     * 根据条件查询单个对象方法
     *
     * @param users
     * @return
     */
    @Override
    public Users getModelByConditions(Users users) {
        return null;
    }

    /**
     * 根据id查询单个对象方法
     *
     * @param id
     * @return
     */
    @Override
    public Users getModelById(Object id) {
        return usersMapper.selectByPrimaryKey(id);
    }

    /**
     * 新增对象方法
     *
     * @param users
     */
    @Override
    public void addModel(Users users) {
        users.setCreateTime(new Date());
        users.setStatus(EnumConstants.StatusEnum.VALID.getCode());
        usersMapper.insertUseGeneratedKeys(users);
    }

    /**
     * 更新对象方法
     *
     * @param users
     */
    @Override
    public void updateModel(Users users) {
        users.setUpdateTime(new Date());
        usersMapper.updateByPrimaryKeySelective(users);
    }

    /**
     * 根据id删除对象方法
     *
     * @param id
     */
    @Override
    public void deleteModelById(Object id) {

    }

    /**
     * 获取分页数据，返回 map对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getModelMapPage(ReqUsersVo vo) {
        return null;
    }

    /**
     * 根据id查询单个对象方法，返回 map对象方法
     *
     * @param id
     * @return
     */
    @Override
    public ResultT getModelMapById(Object id) {
        return ResultT.success(getModelById(id));
    }

    /**
     * 根据条件查询单个对象，返回map对象方法
     *
     * @param users
     * @return
     */
    @Override
    public ResultT getModelMapByConditions(Users users) {
        return null;
    }

    /**
     * 查询列表-map对象
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getResModelListMapByConditions(ReqUsersVo vo) {
        return null;
    }

    /**
     * 根据条件查询res vo对象，返回map对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT getResModelMapByConditions(ReqUsersVo vo) {
        return null;
    }

    /**
     * 更新或插入对象方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT saveOrUpdate(ReqUsersVo vo) {
        if (StringUtils.isNotBlank(vo.getNickName()) && vo.getNickName().length() > 16) {
            return ResultT.fail(EnumConstants.UserErrorCodeEnum.DATA_TO_lONG.getCode());
        }
        if (vo.getId() != null) {
            updateModel(vo);
        } else {
            addModel(vo);
        }
        return ResultT.success(vo);
    }

    /**
     * 根据条件删除方法
     *
     * @param vo
     * @return
     */
    @Override
    public ResultT delete(ReqUsersVo vo) {
        return null;
    }

    /**
     * @return com.wb3.meta.common.pojo.ResultT
     * @Author raopeng
     * @Description //TODO 登录方法
     * @Date 2022/4/2 10:59
     * @Param [reqUsersVo]
     */
    @Override
    public ResultT login(String appid, String code) {
        if (StringUtils.isBlank(code)) {
            return ResultT.fail("jscode不能为空");
        }

        if (!wxMaService.switchover(appid)) {
//            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
            return ResultT.fail("appid无效");
        }
        WxMaJscode2SessionResult session = null;
        try {
            session = wxMaService.getUserService().getSessionInfo(code);

            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            //TODO 可以增加自己的逻辑，关联业务相关数据
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return ResultT.fail("请求微信登录接口失败,"+e.getMessage());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
        ReqUsersVo reqUsersVo = new ReqUsersVo();
        reqUsersVo.setSessionKey(session.getSessionKey());
        reqUsersVo.setOpenId(session.getOpenid());
        reqUsersVo.setUnionId(session.getUnionid());
        ResUsersVo resUsersVo = getResModelByConditions(reqUsersVo);
        //当前钱包已经存在用户表中
        if (resUsersVo != null) {
            if (Objects.equals(resUsersVo.getStatus(), EnumConstants.StatusEnum.INVALID.getCode())) {
                return ResultT.fail("用户已被封禁");
            }
//            BeanUtils.copyProperties(resUsersVo, reqUsersVo);
            reqUsersVo.setId(resUsersVo.getId());
        } else {


            saveOrUpdate(reqUsersVo);

            //新增逻辑，给用户发放一个大姨/榴莲同学，有效期到2024-2-29
//            myToysService.giveToys(reqUsersVo);
        }

        //生成token
        String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSONObject.toJSONString(reqUsersVo), 0);
        reqUsersVo.setToken(token);


        return ResultT.success(reqUsersVo);
    }


}
